package com.gome.boot.config.datasource.multiple;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

/**
 * 数据源切换拦截器.
 * <br/>针对添加了DataSourceType注解的类或方法进行处理.
 *
 * @author baoxiufeng
 */
@Aspect
@Component
@Order(0)
public class DataSourceInterceptor {
    private static final Logger logger = LoggerFactory.getLogger(DataSourceInterceptor.class);

    @Before("@within(type) || @annotation(type)")
    public void before(JoinPoint jp, DataSourceType type) throws Throwable {
        if (type == null) {
            type = jp.getTarget().getClass().getAnnotation(DataSourceType.class);
        }
        String dsType = type.value();
        if (dsType == null || "".equals(dsType)) {
            DataSourceTypeManager.clear();
        } else {
            DataSourceTypeManager.set(dsType);
        }
        logger.debug("[DataSourceInterceptor.before] switch datasource type to [{}]", type.value());
    }

    @After("@within(DataSourceType) || @annotation(DataSourceType)")
    public void after() {
        DataSourceTypeManager.clear();
        logger.debug("[DataSourceInterceptor.after] clear dynamic datasource type.");
    }

    @AfterThrowing("@within(DataSourceType) || @annotation(DataSourceType)")
    public void afterThrowing() {
        DataSourceTypeManager.clear();
        logger.debug("[DataSourceInterceptor.afterThrowing] clear dynamic datasource type.");
    }
}
